﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Win_Oracle
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            this.ShowIcon = false;
            this.ShowInTaskbar = false;
            tabControl1.Enabled = false;
        }

        private void tsbAllTables_Click(object sender, EventArgs e)
        {
            if (this.IsHandleCreated)
            {
                this.Invoke(new MethodInvoker(() => {
                    Application.DoEvents();
                    DataTable dt = DB_Helper.GetTable("select TABLESPACE_NAME, TABLE_NAME from user_tables", null);
                    Application.DoEvents();
                    dataGridView1.DataSource = dt;
                    Application.DoEvents();
                }));                
            }
        }

        private void btnSet_Click(object sender, EventArgs e)
        {
            DB_Helper.SetConn(txtHost.Text.Trim(), txtPort.Text.Trim(), txtSID.Text.Trim(), txtUserName.Text.Trim(), txtPassword.Text.Trim());
            tabControl1.Enabled = true;
        }

        private void tsbGetModel_Click(object sender, EventArgs e)
        {
            if (this.IsHandleCreated)
            {
                this.Invoke(new MethodInvoker(() =>
                {
                    Application.DoEvents();
                    var sel = dataGridView1.SelectedRows;
                    if (sel.Count == 0)
                    {
                        MessageBox.Show("未选中表行");
                        return;
                    }
                    //
                    DataGridViewRow dgvr = sel[0];
                    string tableName = dgvr.Cells[1].Value.ToString();
                    //
                    DataTable dt = DB_Helper.GetTable("select TABLE_NAME, COLUMN_ID, COLUMN_NAME, DATA_TYPE, DATA_LENGTH, DATA_PRECISION, DATA_SCALE from user_tab_columns WHERE TABLE_NAME=:TABLE_NAME order by COLUMN_ID", new List<Oracle.ManagedDataAccess.Client.OracleParameter>() {
                        new Oracle.ManagedDataAccess.Client.OracleParameter("TABLE_NAME", tableName)
                    });
                    Application.DoEvents();
                    //
                    string className = tableName + "Entity";
                    StringBuilder sb = CreateModel(className, dt);
                    textBox1.Text = sb.ToString();
                    tabControl1.SelectedIndex++;
                    Application.DoEvents();
                }));
            }
        }

        private StringBuilder CreateModel(string className, DataTable dt)
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendLine("public class " + className);
            sb.AppendLine("{");
            foreach (DataRow dr in dt.Rows)
            {
                string cid = dr["COLUMN_ID"].ToString();
                string cName = dr["COLUMN_NAME"].ToString();
                string dType = dr["DATA_TYPE"].ToString();
                int dLen = Convert.ToInt32(dr["DATA_LENGTH"].ToString());
                if (dr["DATA_PRECISION"] == DBNull.Value && dr["DATA_SCALE"] == DBNull.Value)
                {
                    if (dType == "CHAR" || dType == "VARCHAR2" || dType == "LONG")
                    {
                        sb.AppendLine(dType + " " + cName + ";");
                    }
                    else if (dType == "DATE")
                    {
                        sb.AppendLine("Date " + cName + ";");
                        sb.Insert(0, "import java.sql.Date;" + Environment.NewLine);
                    }
                }
                else
                {
                    int preLen = Convert.ToInt32(dr["DATA_PRECISION"].ToString());
                    int scaleLen = Convert.ToInt32(dr["DATA_SCALE"].ToString());
                    //整数
                    if (scaleLen == 0)
                    {
                        if (preLen<=4)
                        {
                            sb.AppendLine("short " + cName + ";");
                        }
                        else if (preLen<9)
                        {
                            sb.AppendLine("int " + cName + ";");
                        }
                        else
                        {
                            sb.AppendLine("long " + cName + ";");
                        }
                    }
                    else //小数或float/double
                    {
                        if (preLen + scaleLen <= 10)
                            sb.AppendLine("float " + cName + ";");
                        else
                            sb.AppendLine("double " + cName + ";");
                    }
                }
            }
            sb.AppendLine("}");
            //
            return sb;
        }

        private string OracleType2JavaType(string oracleType)
        {
            switch(oracleType)
            {
                case "DATE":
                    return "DateTime";

                default:
                    return "String";
            }
        }

        private List<Type_OracleJava> _TypeList;
        private void InitTypeList()
        {
            _TypeList = new List<Type_OracleJava>();
            _TypeList.Add(new Type_OracleJava("", "", ""));
        }

        private void btnSelFile_Click(object sender, EventArgs e)
        {
            var r = openFileDialog1.ShowDialog();
            if (r != System.Windows.Forms.DialogResult.OK)
                return;
            //
            txtSQLFilePath.Text = openFileDialog1.FileName;
        }

        private void btnRunSql_Click(object sender, EventArgs e)
        {
            MethodInvoker mi = new MethodInvoker(() =>
            {
                this.Invoke(new MethodInvoker(() => {
                    btnRunSql.Enabled = false;
                    Application.DoEvents();
                }));
                //
                var sqls = System.IO.File.ReadAllLines(txtSQLFilePath.Text.Trim(), Encoding.Default);
                //
                int from = 0;
                this.Invoke(new MethodInvoker(() => {
                    from = Convert.ToInt32(txtFromRow.Text.Trim());
                }));
                //
                for (int i = from - 1; i < sqls.Length; i++)
                {
                    string sql = sqls[i].Trim().TrimEnd(';');
                    DB_Helper.RunNoQuery(sql, new List<Oracle.ManagedDataAccess.Client.OracleParameter>());
                    Output3(string.Format("已执行:{0}", sql));
                }
            });
            //
            AsyncCallback acb = new AsyncCallback(SqlRunOver);
            IAsyncResult iar = mi.BeginInvoke(acb, mi);
        }

        private void SqlRunOver(IAsyncResult iar)
        {
            MethodInvoker mi = iar.AsyncState as MethodInvoker;
            mi.EndInvoke(iar);
            //
            this.Invoke(new MethodInvoker(() =>
            {
                btnRunSql.Enabled = true;
                Application.DoEvents();
            }));
            //
            MessageBox.Show("执行完成");
        }

        private void Output3(string msg)
        {
            if(this.IsHandleCreated)
            {
                this.Invoke(new MethodInvoker(() => {
                    txtOutput3.AppendText(msg);
                    txtOutput3.AppendText(Environment.NewLine);
                    Application.DoEvents();
                }));
            }
        }
    }
}
